package com.example.opengldemo._00_real_light;


import android.opengl.GLSurfaceView;
import android.opengl.GLES30;

import android.os.Build;

import android.view.MotionEvent;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;


import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.view.View;

import com.example.opengldemo.R;
import com.example.opengldemo.util.LoadUtil;
import com.example.opengldemo.util.MatrixState;
import com.example.opengldemo.util.TextureUtil;

import static com.example.opengldemo._00_real_light.Constant.UNIT_SIZE;


@SuppressLint("NewApi")
class MySurfaceView extends GLSurfaceView 
{
	private final float TOUCH_SCALE_FACTOR = 180.0f/320;
    private SceneRenderer mRenderer;
    
    private float mPreviousY;
    private float mPreviousX;
    

    float cx=0;
    float cy=2;
    float cz=24;
    float cAngle=0;

    int textureIdCM;
    int[] textureIdA=new int[6];
	
	@TargetApi(Build.VERSION_CODES.CUPCAKE)
	@SuppressLint("NewApi")
	public MySurfaceView(Context context) {
        super(context);
        this.setEGLContextClientVersion(3);
        mRenderer = new SceneRenderer();
        setRenderer(mRenderer);
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    @Override 
    public boolean onTouchEvent(MotionEvent e) 
    {
        float y = e.getY();
        float x = e.getX();
        switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dy = y - mPreviousY;
            float dx = x - mPreviousX;
            cAngle+=dx * TOUCH_SCALE_FACTOR;
            cx=(float) (Math.sin(Math.toRadians(cAngle))*24f);
            cz=(float) (Math.cos(Math.toRadians(cAngle))*24f);
            cy+=dy/10.0f;

            MatrixState.setCamera(cx,cy,cz,0f,0f,0f,0f,1.0f,0.0f);
        }
        mPreviousY = y;
        mPreviousX = x;
        return true;
    }

	private class SceneRenderer implements Renderer
    {  
		float yAngle;
    	float zAngle;

        TextureRect texRect ;
        Obj_Vertex_Normal_Texcoors_Demo lovo ;


        public void onDrawFrame(GL10 gl) 
        {
            GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);

            MatrixState.pushMatrix();

            MatrixState.rotate(yAngle, 0, 1, 0);
            MatrixState.rotate(zAngle, 1, 0, 0);            

            if(lovo!=null)
            {
            	lovo.drawSelf(textureIdCM);
            }   
            MatrixState.popMatrix();               

            final float tzz=0.4f;            

            MatrixState.pushMatrix();
            MatrixState.translate(0, 0, -UNIT_SIZE+tzz);
            texRect.drawSelf(textureIdA[0]);
            MatrixState.popMatrix();              

            MatrixState.pushMatrix();
            MatrixState.translate(0, 0, UNIT_SIZE-tzz);
            MatrixState.rotate(180, 0, 1, 0);
            texRect.drawSelf(textureIdA[5]);
            MatrixState.popMatrix(); 

            MatrixState.pushMatrix();
            MatrixState.translate(-UNIT_SIZE+tzz, 0, 0);
            MatrixState.rotate(90, 0, 1, 0);
            texRect.drawSelf(textureIdA[1]);
            MatrixState.popMatrix(); 

            MatrixState.pushMatrix();
            MatrixState.translate(UNIT_SIZE-tzz, 0, 0);
            MatrixState.rotate(-90, 0, 1, 0);
            texRect.drawSelf(textureIdA[2]);
            MatrixState.popMatrix();

            MatrixState.pushMatrix();
            MatrixState.translate(0, -UNIT_SIZE+tzz, 0);
            MatrixState.rotate(-90, 1, 0, 0);
            texRect.drawSelf(textureIdA[3]);
            MatrixState.popMatrix(); 

            MatrixState.pushMatrix();
            MatrixState.translate(0, UNIT_SIZE-tzz, 0);
            MatrixState.rotate(90, 1, 0, 0);
            texRect.drawSelf(textureIdA[4]);
            MatrixState.popMatrix(); 
        }  

        @SuppressLint("NewApi")
		public void onSurfaceChanged(GL10 gl, int width, int height) 
        {
        	GLES30.glViewport(0, 0, width, height); 

            float ratio = (float) width / height;
            MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 2, 1000);
            MatrixState.setCamera(cx,cy,cz,0f,0f,0f,0f,1.0f,0.0f);
            
            new Thread()
            {
            	public void run()
            	{
            		while(true)
            		{
            			mRenderer.yAngle += 5;
            			mRenderer.zAngle+= 3;
            			  
            			try {
							Thread.sleep(100);
						} catch (InterruptedException e) 
						{
							e.printStackTrace();
						}
            		}
            	}
            }.start();
        }  

        @SuppressLint("NewApi")
		public void onSurfaceCreated(GL10 gl, EGLConfig config) 
        {
            GLES30.glClearColor(0.0f,0.0f,0.0f,1.0f);    

            GLES30.glEnable(GLES30.GL_DEPTH_TEST);

            GLES30.glEnable(GLES30.GL_CULL_FACE);

            MatrixState.setInitStack();

            LoadUtil.getLoadObj(MySurfaceView.this, "z_real_light/ball.obj", new LoadUtil.CreateObjectLoader() {
                @Override
                public void create(View view, float[] vertexArray, float[] normalArray, float[] texcoorsArray) {
                    lovo = new Obj_Vertex_Normal_Texcoors_Demo(view , vertexArray , normalArray , texcoorsArray);
                }
            });
            texRect=new TextureRect(MySurfaceView.this , UNIT_SIZE);

            int[] cubeMapResourceIds = new int[]
            {
                    R.raw.skycubemap_right, R.raw.skycubemap_left, R.raw.skycubemap_up_cube ,
                    R.raw.skycubemap_down_cube, R.raw.skycubemap_front, R.raw.skycubemap_back
            };
            textureIdCM=TextureUtil.get3DTextureId(MySurfaceView.this  , cubeMapResourceIds) ;

            textureIdA[0]= TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_right , null , false);
            textureIdA[1]=TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_left , null , false);
            textureIdA[2]=TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_front , null , false);
            textureIdA[3]=TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_down , null , false);
            textureIdA[4]=TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_up , null , false);
            textureIdA[5]=TextureUtil.getTextureId(MySurfaceView.this , R.raw.skycubemap_back , null , false);
        }
    }
}
